package dormouse.vfs.metadata;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;

import org.apache.commons.vfs2.FileObject;


/**
 * This class contains a series of Factory methods used to create
 * MetadataReaders and to get the metadata for FileObjects. 
 *
 */
public class MetadataReaderFactory {
	
	
	static Map<String, IMetadataReader> extensionMap = new HashMap<String, IMetadataReader>();
	
	static{
		ServiceLoader<IMetadataReader> loader = ServiceLoader.load(IMetadataReader.class);
        Iterator<IMetadataReader> mdReaderIt = loader.iterator();
        IMetadataReader currReader = null;
        String[] exts = null;
        String ext = null;
        
        while(mdReaderIt.hasNext()){
            currReader = mdReaderIt.next();
            exts = currReader.getFileExtensions();
            if (exts != null){
                for (int i=0; i < exts.length; i++){
                    extensionMap.put(exts[i], currReader);
                }
            }
        }
	}

	/**
	 * This method gets the metadata for a given file object.
	 * If the extension of the file does not match one of the
	 * supported extensions, then null is returned.
	 * @param file	The file whose metadata you want to get.
	 * @return		A map containing the metadata for the file.
	 */
	public static Map<String, String> getMetadata(FileObject file) throws IOException{
		IMetadataReader reader = null;
		reader = getInstance(file);
		return (reader != null)?reader.getMetadata(file):null;
	}
	
	/**
	 * This method gets the instance of a IMetadataReader
	 * for a given file object. If the extension of the file 
	 * does not match one of the
	 * supported extensions, then null is returned.
	 * 
	 * @param file	The file whose metadata you want to read.
	 * @return
	 */
	public static IMetadataReader getInstance(FileObject file){
		String ext = file.getName().getExtension();
		if (ext != null){
			ext = ext.toLowerCase();
		}
		return getInstance(ext);
	}
	
	/**
	 * This method gets an instance of a IMetadataReader
	 * based on the extension of a file.  If the extension
	 * of the file does not match one of the supported extensions
	 * then null is returned.
	 * 
	 * @param ext
	 * @return
	 */
	public static IMetadataReader getInstance(String ext){
		IMetadataReader reader = null;
		reader = extensionMap.get(ext);
		return reader;
		
	}
	
	/**
	 * This method returns the metadata keys for a given file extension.
	 * The metadata is stored in a map, the keys represent the 
	 * metadata field names (i.e. title, author, creation date, etc).
	 * 
	 * @param file
	 * @return  May return null if there is no IMetadataReader defined
	 * 			for this file type.
	 */
	public static Set<String> getMetadataKeys(FileObject file){
		IMetadataReader reader = getInstance(file);
		return (reader != null)?reader.getMetadataKeys():null;
	}
	
	/**
	 * This method returns the metadata keys for a given extension
	 * 
	 * @param ext  The file extension.
	 * @return  May return null if there is no IMetadataReader defined
	 * 			for this file type.
	 */
	public static Set<String> getMetadataKeys(String ext){
		IMetadataReader reader = getInstance(ext);
		return (reader != null)?reader.getMetadataKeys():null;
	}
	
	
	private static boolean isInFileClass(String ext, String[] extList){
		boolean isIn = false;
		
		for(int i=0; i < extList.length; i++){
			if (ext.equalsIgnoreCase(extList[i])){
				isIn = true;
				break;
			}
		}
		
		return isIn;
	}
	
	
}
